/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.business.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.iai.v20200303.IaiClient;
import com.tencentcloudapi.iai.v20200303.models.VerifyPersonRequest;
import com.tencentcloudapi.iai.v20200303.models.VerifyPersonResponse;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.business.domain.BisVerifyPerson;
import me.zhengjie.business.domain.sup.Rygl;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.face.FaceUtil;
import me.zhengjie.face.config.FaceConfig;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.business.repository.BisVerifyPersonRepository;
import me.zhengjie.business.service.BisVerifyPersonService;
import me.zhengjie.business.service.dto.BisVerifyPersonDto;
import me.zhengjie.business.service.dto.BisVerifyPersonQueryCriteria;
import me.zhengjie.business.service.mapstruct.BisVerifyPersonMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author xiahongbo
* @date 2023-11-26
**/
@Slf4j
@Service
@RequiredArgsConstructor
public class BisVerifyPersonServiceImpl implements BisVerifyPersonService {

    private final BisVerifyPersonRepository bisVerifyPersonRepository;
    private final BisVerifyPersonMapper bisVerifyPersonMapper;

    @Override
    public Map<String,Object> queryAll(BisVerifyPersonQueryCriteria criteria, Pageable pageable){
        Page<BisVerifyPerson> page = bisVerifyPersonRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(bisVerifyPersonMapper::toDto));
    }

    @Override
    public List<BisVerifyPersonDto> queryAll(BisVerifyPersonQueryCriteria criteria){
        return bisVerifyPersonMapper.toDto(bisVerifyPersonRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public BisVerifyPersonDto findById(Long id) {
        BisVerifyPerson bisVerifyPerson = bisVerifyPersonRepository.findById(id).orElseGet(BisVerifyPerson::new);
        ValidationUtil.isNull(bisVerifyPerson.getId(),"BisVerifyPerson","id",id);
        return bisVerifyPersonMapper.toDto(bisVerifyPerson);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BisVerifyPersonDto create(BisVerifyPerson resources) {
        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
        resources.setId(snowflake.nextId()); 
        return bisVerifyPersonMapper.toDto(bisVerifyPersonRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(BisVerifyPerson resources) {
        BisVerifyPerson bisVerifyPerson = bisVerifyPersonRepository.findById(resources.getId()).orElseGet(BisVerifyPerson::new);
        ValidationUtil.isNull( bisVerifyPerson.getId(),"BisVerifyPerson","id",resources.getId());
        bisVerifyPerson.copy(resources);
        bisVerifyPersonRepository.save(bisVerifyPerson);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            bisVerifyPersonRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<BisVerifyPersonDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (BisVerifyPersonDto bisVerifyPerson : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public JSONObject veryfyPerson(Map<String, String> map) {
        log.info("[BisVerifyPersonServiceImpl - veryfyPerson]--------------- 人员验证 start");
        JSONObject obj = new JSONObject();
        try{
            String userId = map.get("userId");
            String url = map.get("url");
            String orderId = map.get("orderId");

            JSONObject userJson = new JSONObject();
            userJson.put("PersonId", userId);
            userJson.put("Url", url);
            userJson.put("QualityControl", 4);
            userJson.put("NeedRotateDetection", 0);

            String action = "VerifyFace";

            log.info("[BisVerifyPersonServiceImpl - veryfyPerson]--------------- 连接人脸识别服务 ");
            String resp = FaceUtil.doRequest(FaceConfig.secretId, FaceConfig.secretKey, action, userJson.toString(), FaceConfig.apiUrl);
            String response = resp;
            log.info("[BisVerifyPersonServiceImpl - veryfyPerson]--------------- 腾讯云人脸识别返回结果：{}", resp);
            log.info("[BisVerifyPersonServiceImpl - veryfyPerson]--------------- 连接人脸识别服务成功 ");
            // 返回的resp是一个CreatePersonResponse的实例，与请求对象对应
            JSONObject respJson = JSONObject.parseObject(resp).getJSONObject("Response");

            String Score = respJson.containsKey("Score") ? respJson.getString("Score") : "";
            String IsMatch = respJson.containsKey("IsMatch") ? respJson.getString("IsMatch") : "";
            String errorMsg = respJson.containsKey("Error") ? respJson.getJSONObject("Error").getString("Message") : "";

            if(me.zhengjie.utils.StringUtils.isEmpty(errorMsg)) {

                if("true".equals(IsMatch)) {
                    // 输出json格式的字符串回包
                    BisVerifyPerson verifyPerson = new BisVerifyPerson();
                    verifyPerson.setOrderId(orderId);
                    verifyPerson.setUserId(Long.parseLong(userId));
                    verifyPerson.setImageUrl(url);
                    verifyPerson.setIsMatch(IsMatch);
                    verifyPerson.setResponse(response);

                    obj.put("flag", "1");
                    obj.put("isMatch", IsMatch);

                    log.info("[BisVerifyPersonServiceImpl - veryfyPerson]--------------- 保存验证结果");
                    this.create(verifyPerson);
                }

            } else {
                log.info("[BisVerifyPersonServiceImpl - veryfyPerson]--------------- 报错：{}", errorMsg);
                obj.put("flag", "0");
                obj.put("isMatch", "false");
                obj.put("msg", errorMsg);
            }

        }catch (NoSuchAlgorithmException e) {
            log.info("[BisVerifyPersonServiceImpl - veryfyPerson]--------------- 人员验证报错：{}" + e.toString());
            obj.put("flag", "0");
            obj.put("isMatch", "false");
            obj.put("msg", "头像校验失败，请联系管理员");
            e.printStackTrace();
        } catch (IOException e) {
            log.info("[BisVerifyPersonServiceImpl - veryfyPerson]--------------- 人员验证报错：{}" + e.toString());
            obj.put("flag", "0");
            obj.put("isMatch", "false");
            obj.put("msg", "头像校验失败，请联系管理员");
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            log.info("[BisVerifyPersonServiceImpl - veryfyPerson]--------------- 人员验证报错：{}" + e.toString());
            obj.put("flag", "0");
            obj.put("isMatch", "false");
            obj.put("msg", "头像校验失败，请联系管理员");
            e.printStackTrace();
        }
        return obj;
    }
}